package com.showsu.editor.utils.aliyun;

import com.aliyun.ice20201109.Client;
import com.aliyun.ice20201109.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Collections;


/**
 * @Author: Johnplue
 * @Description: 阿里云ICE工具类
 * @Date: Created in 15:49 下午 2023/12/21
 * @Modified By:
 */
@Slf4j
@Component
public class ICESubmitJobsUtil extends BaseAliyunUtil<Client> {


    @Value("${aliyun.mps.endpoint.ice}")
    private String endpoint;

    @Value("${aliyun.mps.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.mps.accessKeySecret}")
    private String accessKeySecret;

    private String bucket="showsu";

    @Override
    public void initClient(String accessKeyId, String accessKeySecret, String endpoint) {
        try {
            this.client= this.createClient(accessKeyId,accessKeySecret,endpoint);
        }catch (Exception e) {
            System.out.println("阿里云ICE工具类 实例化报错："+e.getMessage());
            throw new RuntimeException(e);
        }

    }
    @PostConstruct
    public void init(){
        System.out.println("开始实例化 阿里云ICE工具类");
        this.initClient(accessKeyId,accessKeySecret,endpoint);
        System.out.println("结束实例化 阿里云ICE工具类");
    }

    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @param endpoint
     * @return Client
     * @throws Exception
     */
    public Client createClient(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
        Config config = new Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // Endpoint 请参考 https://api.aliyun.com/product/Mts
        config.endpoint =endpoint;
        return new Client(config);
    }


    public TranscodeJobResult run(Client client,SubmitTranscodeJobRequest submitTranscodeJobRequest){
        TranscodeJobResult result=new TranscodeJobResult();
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            SubmitTranscodeJobResponse resp=client.submitTranscodeJobWithOptions(submitTranscodeJobRequest, runtime);
            result.setStatusCode(resp.getStatusCode().toString());
            result.setParentJobId(resp.getBody().getTranscodeParentJob().parentJobId);
            result.setPercent(resp.getBody().getTranscodeParentJob().getPercent());
            result.setStatus(resp.getBody().getTranscodeParentJob().getStatus());
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            result.setErrorCode(error.code);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            result.setErrorCode(error.code);
        }
        return result;
    }

    public TranscodeJobResult runSync(Client client,SubmitTranscodeJobRequest submitTranscodeJobRequest){
        TranscodeJobResult submitJobsResult=this.run(client,submitTranscodeJobRequest);
        if(StringUtils.isNotBlank(submitJobsResult.getErrorCode())||!"200".equals(submitJobsResult.getStatusCode())){
            return submitJobsResult;
        }
        //等待1s 增加转码任务完成概率
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        int i=2;
        while (true){
            TranscodeJobResult transcodeJobResult=this.getTranscodeJob(submitJobsResult.getParentJobId());
//            log.info(JSON.toJSONString(transcodeJobResult));
            if(StringUtils.isNotBlank(submitJobsResult.getErrorCode())||!"200".equals(submitJobsResult.getStatusCode())){
                return transcodeJobResult;
            }
            if(transcodeJobResult.getPercent()>=100L){
                log.info("视频转码完毕"+transcodeJobResult.getParentJobId());
                return transcodeJobResult;
            }
            log.info("等待视频转码"+1000*i+"毫秒"+transcodeJobResult.getParentJobId());
            try {
                if(i<=60){
                    Thread.sleep(1000*i);
                }else{
                    log.info("视频转码中，服务器不再等待返回当前任务状态"+transcodeJobResult.getParentJobId());
                    return transcodeJobResult;
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            i++;
        }
    }


    private SubmitTranscodeJobRequest getSubmitTranscodeJobRequest(String bucket,String object,String outputBucket,String outputObject,String templateId){
        SubmitTranscodeJobRequest.SubmitTranscodeJobRequestInputGroup inputGroup0 = new SubmitTranscodeJobRequest.SubmitTranscodeJobRequestInputGroup()
                // String, 必填, 媒体对象类型。 取值：  - OSS: OSS文件。 - Media: 媒资 ID。
                .setType("OSS")
                // String, 必填, 媒体值： - type 为 OSS 时，为 URL, 支持 OSS 协议和 HTTP 协议。 > URL中的 OSS bucket 需要先添加到IMS[存储管理](~~440592~~)后再使用。  - type 为 Media 时，为媒资 ID。
                .setMedia("oss://"+bucket+"/"+object);
        SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroupProcessConfigTranscode outputGroup0ProcessConfigTranscode = new SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroupProcessConfigTranscode()
                // String, 必填, 模板 ID。
                .setTemplateId(templateId);
        SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroupProcessConfig outputGroup0ProcessConfig = new SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroupProcessConfig()
                // Object, 可选
                .setTranscode(outputGroup0ProcessConfigTranscode);
        SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroupOutput outputGroup0Output = new SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroupOutput()
                // String, 必填, 媒体对象类型。 取值：  - OSS: OSS文件。 - Media: 媒资 ID。
                .setType("OSS")
                // String, 必填, 媒体值： - type 为 OSS 时，为 URL, 支持 OSS 协议和 HTTP 协议。 > URL中的 OSS bucket 需要先添加到IMS[存储管理](~~440592~~)后再使用。  - type 为 Media 时，为媒资 ID。
                .setMedia("oss://"+outputBucket+"/"+outputObject);
        SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroup outputGroup0 = new SubmitTranscodeJobRequest.SubmitTranscodeJobRequestOutputGroup()
                // Object, 可选
                .setOutput(outputGroup0Output)
                // Object, 可选
                .setProcessConfig(outputGroup0ProcessConfig);
        return new SubmitTranscodeJobRequest()
                // Array, 可选
                .setInputGroup(Collections.singletonList(
                        inputGroup0
                ))
                // Array, 可选
                .setOutputGroup(Collections.singletonList(
                        outputGroup0
                ));
    }

    public TranscodeJobResult submitTranscodeJob(Client thisClient,String bucket,String object,String outputBucket,String outputObject,String templateId,Boolean isSync) {
        SubmitTranscodeJobRequest submitTranscodeJobRequest = getSubmitTranscodeJobRequest(bucket,object,outputBucket,outputObject,templateId);
        if(isSync){
            return runSync(thisClient,submitTranscodeJobRequest);
        }
        return run(thisClient,submitTranscodeJobRequest);
    }

    public TranscodeJobResult submitTranscodeJob(String accessKeyId,String accessKeySecret,String endpoint,String bucket,String object,String outputBucket,String outputObject,String templateId,Boolean isSync){
        try {
            Client newClient= this.createClient(accessKeyId,accessKeySecret,endpoint);
            return submitTranscodeJob(newClient,bucket,object,outputBucket,outputObject,templateId,isSync);
        }catch (Exception e) {
            log.error("start方法 阿里云ICE工具类 实例化报错："+e.getMessage());
            throw new RuntimeException(e);
        }
    }


    public TranscodeJobResult submitTranscodeJob(String bucket,String object,String outputBucket,String outputObject,String templateId,Boolean isSync) {
        if(this.client==null){
            return submitTranscodeJob(accessKeyId,accessKeySecret,endpoint,bucket,object,outputBucket,outputObject,templateId,isSync);
        }
        return submitTranscodeJob(this.client,bucket,object,outputBucket,outputObject,templateId,isSync);
    }

    public TranscodeJobResult submitTranscodeJob(String object,String outputObject,String templateId,Boolean isSync) {
        return submitTranscodeJob(this.bucket,object,this.bucket,outputObject,templateId,isSync);
    }

    public TranscodeJobResult submitTranscodeJob(String object,String outputObject,TranscodeTemplateEnum templateEnum,Boolean isSync) {
        return submitTranscodeJob(object,outputObject,templateEnum.getTemplateId(),isSync);
    }




    public TranscodeJobResult getTranscodeJob(Client thisClient,String parentJobId){
        TranscodeJobResult result=new TranscodeJobResult();
        GetTranscodeJobRequest getTranscodeJobRequest = new GetTranscodeJobRequest()
                .setParentJobId(parentJobId);
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            GetTranscodeJobResponse resp = thisClient.getTranscodeJobWithOptions(getTranscodeJobRequest, runtime);
            result.setStatusCode(resp.getStatusCode().toString());
            result.setParentJobId(resp.getBody().getTranscodeParentJob().parentJobId);
            result.setPercent(resp.getBody().getTranscodeParentJob().getPercent());
            result.setStatus(resp.getBody().getTranscodeParentJob().getStatus());
        } catch (TeaException error) {
            com.aliyun.teautil.Common.assertAsString(error.message);
            result.setErrorCode(error.code);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            result.setErrorCode(error.code);
        }
        return result;
    }

    public TranscodeJobResult getTranscodeJob(String accessKeyId,String accessKeySecret,String endpoint,String parentJobId){
        try {
            Client newClient= this.createClient(accessKeyId,accessKeySecret,endpoint);
            return getTranscodeJob(newClient,parentJobId);
        }catch (Exception e) {
           log.error("getTranscodeJob方法 阿里云ICE工具类 实例化报错："+e.getMessage());
            throw new RuntimeException(e);
        }

    }

    public TranscodeJobResult getTranscodeJob(String parentJobId){
        if(this.client==null){
            return getTranscodeJob(accessKeyId,accessKeySecret,endpoint,parentJobId);
        }
        return getTranscodeJob(this.client,parentJobId);
    }

    public MediaInfoJobResult submitSyncMediaInfoJob(Client thisClient,String bucket,String object){
        MediaInfoJobResult result=new MediaInfoJobResult();
        SubmitSyncMediaInfoJobRequest.SubmitSyncMediaInfoJobRequestInput input = new SubmitSyncMediaInfoJobRequest.SubmitSyncMediaInfoJobRequestInput()
                .setType("OSS")
                .setMedia("oss://"+bucket+"/"+object);
        SubmitSyncMediaInfoJobRequest submitSyncMediaInfoJobRequest = new SubmitSyncMediaInfoJobRequest()
                .setInput(input);
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            SubmitSyncMediaInfoJobResponse resp=thisClient.submitSyncMediaInfoJobWithOptions(submitSyncMediaInfoJobRequest, runtime);
            result.setStatusCode(resp.getStatusCode().toString());
            result.setStatus(resp.getBody().getMediaInfoJob().getStatus());
            SubmitSyncMediaInfoJobResponseBody.SubmitSyncMediaInfoJobResponseBodyMediaInfoJobMediaInfoProperty mediaInfoProperty=resp.getBody().getMediaInfoJob().getMediaInfoProperty();
            result.setDuration(mediaInfoProperty.getFileBasicInfo().getDuration());
            result.setFileSize(mediaInfoProperty.getFileBasicInfo().getFileSize());
            result.setWidth(mediaInfoProperty.getFileBasicInfo().getWidth());
            result.setHeight(mediaInfoProperty.getFileBasicInfo().getHeight());
            result.setBitrate(mediaInfoProperty.getFileBasicInfo().getBitrate());
            result.setFps(mediaInfoProperty.getVideoStreamInfoList().get(0).getFps());
        } catch (TeaException error) {;
            com.aliyun.teautil.Common.assertAsString(error.message);
            result.setErrorCode(error.code);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            com.aliyun.teautil.Common.assertAsString(error.message);
            result.setErrorCode(error.code);
        }
        return result;
    }

    public MediaInfoJobResult submitSyncMediaInfoJob(String accessKeyId,String accessKeySecret,String endpoint,String bucket,String object){
        try {
            Client newClient= this.createClient(accessKeyId,accessKeySecret,endpoint);
            return submitSyncMediaInfoJob(newClient,bucket,object);
        }catch (Exception e) {
            log.error("submitSyncMediaInfoJob方法 阿里云ICE工具类 实例化报错："+e.getMessage());
            throw new RuntimeException(e);
        }
    }
    public MediaInfoJobResult submitSyncMediaInfoJob(String object){
        if(this.client==null){
            return submitSyncMediaInfoJob(accessKeyId,accessKeySecret,endpoint,this.bucket,object);
        }
        return submitSyncMediaInfoJob(this.client,this.bucket,object);
    }
}
